package com.zhz.mall.common.util.threadpool;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.task.TaskDecorator;
import org.springframework.lang.NonNull;

import java.util.Objects;

/**
 * ErrorLoggingTaskDecorator
 * <p>
 * 注意：对于 submit 提交的任务，出现异常时会将异常信息保存在 future 中，所以 ErrorLoggingTaskDecorator 是无效的。
 *
 * @author zhouhengzhe
 */
@Slf4j
public class ErrorLoggingTaskDecorator implements TaskDecorator {

    public static final ErrorLoggingTaskDecorator INSTANCE = new ErrorLoggingTaskDecorator();

    @NonNull
    @Override
    public Runnable decorate(@NonNull Runnable runnable) {
        return () -> {
            try {
                runnable.run();
                // 当使用 submit 提交任务时, 此时的 runnable 为 FutureTask，最终的异常信息会被保存在 FutureTask 内部而不会直接抛出
                // 这里还是决定不对 FutureTask 进行处理, 因为应该由调用方（future.get()）来决定如何处理异常, 而不是直接在这里记录错误日志
//                if (runnable instanceof FutureTask) {
//                    FutureTask futureTask = (FutureTask) runnable;
//                    futureTask.get();
//                }
            } catch (Throwable cause) {
                log.error("线程池目标线程[{}]执行异常: {}", Thread.currentThread(), getMessage(cause), cause);
                throw cause;
            }
        };
    }


    /**
     * 获取异常信息，当异常信息为空时，返回异常名
     */
    private String getMessage(Throwable cause) {
        return Objects.nonNull(cause.getMessage()) ? cause.getMessage() : cause.getClass().getName();
    }


}
